/**
 * Created by meiguizhinian on 2018/7/3
 * Copyright © 2018 lixiaolong. All rights reserved.
 */

//TODO：等待完成
//cocos2dx class
ivy.UIButton = ivy.UIAniBox.extend({
	_className:"ivy.UIButton",
	ctor : function (formName, blockName, sourceControlData) {
		this._super();
		this._buttonSureActionID  = new ivy.IDBaseT();
		this._normalAniID  = new ivy.AnimationID();
		this._pressedAniID  = new ivy.AnimationID();
		if (formName && blockName && sourceControlData) {
			this.initWith(formName, blockName, sourceControlData)
		}
	},

	/**
	 * void initWith(int32_t formID, int32_t blockID, TouchMode touchMode = TouchMode::eSingleTouch);
	 * void initWith(const std::string& formName, const std::string& blockName, const cc::UISourceControlData& sourceControlData, bool trueType = false);
	 * void initWith(std::string aniFileName, int32_t actionID, cc::AniPlayState aniShowState = cc::AniPlayState::ePause, TouchMode touchMode = TouchMode::eSingleTouch);
	 */
	initWith : function() {
		if (cc.isNumber(arguments[0])) {
			this._super(arguments[0], arguments[1]);
			this.setCascadeColorAndOpacityEnabled(true);
			this.touchMode_ = arguments.length>2 ? arguments[2] : ivy.TouchMode.eSingleTouch;
			if (this.touchMode_ === ivy.TouchMode.eMulitTouch) {
				// auto listener1 = cocos2d::EventListenerTouchAllAtOnce::create();
				// listener1->onTouchesBegan = CC_CALLBACK_2(UIButton::onTouchesBegan, this);
				// listener1->onTouchesMoved = CC_CALLBACK_2(UIButton::onTouchesMoved, this);
				// listener1->onTouchesEnded = CC_CALLBACK_2(UIButton::onTouchesEnded, this);
				// _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, this);
			} else {
				let listener = cc.EventListener.create({
					event : cc.EventListener.TOUCH_ONE_BY_ONE,
					swallowTouches : true,
					onTouchBegan : this.onTouchBegan.bind(this),
					onTouchMoved : this.onTouchMoved.bind(this),
					onTouchEnded : this.onTouchEnded.bind(this),
				});
				cc.eventManager.addListener(listener, this);
				this.setTouchListener(listener);
				this.setSwallowTouches(true);
			}
		} else if (cc.isString(arguments[0])) {
			if (cc.isNumber(arguments[1])) {
				let aniShowState = arguments.length>2 ? arguments[2] : ivy.AniPlayState.ePause;
				this.touchMode_ = arguments.length>3 ? arguments[3] : ivy.TouchMode.eSingleTouch;
				this.setCascadeColorAndOpacityEnabled(true);
				this._aniPlayer = ivy.AniPlayer.create(arguments[0], arguments[1], 0, true, aniShowState);
				this.addChild(this._aniPlayer);
				if (this.touchMode_ === ivy.TouchMode.eMulitTouch) {
					// auto listener1 = cocos2d::EventListenerTouchAllAtOnce::create();
					// listener1->onTouchesBegan = CC_CALLBACK_2(UIButton::onTouchesBegan, this);
					// listener1->onTouchesMoved = CC_CALLBACK_2(UIButton::onTouchesMoved, this);
					// listener1->onTouchesEnded = CC_CALLBACK_2(UIButton::onTouchesEnded, this);
					// _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, this);
				} else {
					let listener = cc.EventListener.create({
						event : cc.EventListener.TOUCH_ONE_BY_ONE,
						swallowTouches : true,
						onTouchBegan : this.onTouchBegan.bind(this),
						onTouchMoved : this.onTouchMoved.bind(this),
						onTouchEnded : this.onTouchEnded.bind(this),
					});
					cc.eventManager.addListener(listener, this);

					this.setTouchListener(listener);
					this.setSwallowTouches(true);
				}
			} else if (cc.isString(arguments[1])) {
				let formName = arguments[0];
				let blockName = arguments[1];
				let sourceControlData = arguments[2];
				let trueType = arguments.length>3 ? arguments[3] : false;
				//string formName, string blockName, const cc::UISourceControlData& sourceControlData

				let uim = ivy.UIManager.getInstance();
				this._super(formName, arguments[1], sourceControlData);
				let isMulitTouch = uim.getControlListDataByFindIndex(sourceControlData.propertyDataFindIndex[ivy.DefaultSourceControlTypes.SCT_ELEMENT_AniButton_MulitTouch_list]);
				this._clickActionIndex = uim.getControlActionDataByFindIndex(sourceControlData.propertyDataFindIndex[ivy.DefaultSourceControlTypes.SCT_ELEMENT_AniButton_ClickAction_action]);
				this._unClickActionIndex = uim.getControlActionDataByFindIndex(sourceControlData.propertyDataFindIndex[ivy.DefaultSourceControlTypes.SCT_ELEMENT_AniButton_UnClickAction_action]);
				this._buttonSureActionID.setValue(uim.getControlActionDataByFindIndex(sourceControlData.propertyDataFindIndex[ivy.DefaultSourceControlTypes.SCT_ELEMENT_AniButton_SureAction_action]));
				if (sourceControlData.propertyDataFindIndex.length > ivy.DefaultSourceControlTypes.SCT_ELEMENT_AniButton_ShowType_list&& trueType) {
					this._showType = uim.getControlListDataByFindIndex(sourceControlData.propertyDataFindIndex[ivy.DefaultSourceControlTypes.SCT_ELEMENT_AniButton_ShowType_list]);
					if (this._showType !== ivy.UIButtonShowType.eComputerAniShow) {
						let uim = ivy.UIManager.getInstance();
						let aniIDInUI = uim.getBlockDataByType(formName, blockName, ivy.UIManager.FormDataType.eBgAniID);
						let actionIDInUI = uim.getBlockDataByType(formName, blockName, ivy.UIManager.FormDataType.eBgActionID);
						let seqIDInUI = uim.getBlockDataByType(formName, blockName, ivy.UIManager.FormDataType.eBgSeqID);
						let aniIDInUISel = uim.getBlockDataByType(formName, blockName, ivy.UIManager.FormDataType.eSelBgAniID);
						let actionIDInUISel = uim.getBlockDataByType(formName, blockName, ivy.UIManager.FormDataType.eSelBgActionID);
						let seqIDInUISel = uim.getBlockDataByType(formName, blockName, ivy.UIManager.FormDataType.eSelBgSeqID);
						let aniFileNameNormal = uim.getAniFileNameByUIAniID(aniIDInUI);
						let aniFileNamePressed = uim.getAniFileNameByUIAniID(aniIDInUISel);
						let classID = ivy.SceneCommonDataManager.getInstance().getClassIDByAniFileName(aniFileNameNormal);
						cc.assert(classID!==-1);
						this._normalAniID = new ivy.AnimationID(classID, actionIDInUI);
						classID = ivy.SceneCommonDataManager.getInstance().getClassIDByAniFileName(aniFileNamePressed);
						assert(classID !== -1);
						if(this._showType === ivy.UIButtonShowType.eTwoPartsAniShowPressedNotCircle) {
							this._pressedAniID = new ivy.AnimationID(classID, actionIDInUISel, 0, true, ivy.AniPlayState.eNotCircle);
						} else {
							this._pressedAniID = new ivy.AnimationID(classID, actionIDInUISel);
						}
					}
				}
				if (isMulitTouch === 1) {
					this.touchMode_ = ivy.UIBase.TouchMode.eMulitTouch;
				} else {
					this.touchMode_ = ivy.UIBase.TouchMode.eSingleTouch;
				}
				this.setCascadeColorAndOpacityEnabled(true);
				if (this.touchMode_ === ivy.UIBase.TouchMode.eMulitTouch) {
					// auto listener1 = cocos2d::EventListenerTouchAllAtOnce::create();
					// listener1->onTouchesBegan = CC_CALLBACK_2(UIButton::onTouchesBegan, this);
					// listener1->onTouchesMoved = CC_CALLBACK_2(UIButton::onTouchesMoved, this);
					// listener1->onTouchesEnded = CC_CALLBACK_2(UIButton::onTouchesEnded, this);
					// _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, this);
				} else {
					// auto listener1 = cocos2d::EventListenerTouchOneByOne::create();
					// listener1->onTouchBegan = CC_CALLBACK_2(UIButton::onTouchBegan, this);
					// listener1->onTouchMoved = CC_CALLBACK_2(UIButton::onTouchMoved, this);
					// listener1->onTouchEnded = CC_CALLBACK_2(UIButton::onTouchEnded, this);
					// listener1->onTouchCancelled = CC_CALLBACK_2(UIButton::onTouchCancel, this);
					// _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, this);
					// this.setTouchListener(listener1);

					let listener = cc.EventListener.create({
						event : cc.EventListener.TOUCH_ONE_BY_ONE,
						swallowTouches : true,
						onTouchBegan : this.onTouchBegan.bind(this),
						onTouchMoved : this.onTouchMoved.bind(this),
						onTouchEnded : this.onTouchEnded.bind(this),
						onTouchCancelled : this.onTouchCancelled.bind(this),
					});
					cc.eventManager.addListener(listener, this);

					this.setTouchListener(listener);
					let st = uim.getControlActionDataByFindIndex(sourceControlData.propertyDataFindIndex[ivy.DefaultSourceControlTypes.SCT_ELEMENT_AniButton_SwallowTouches_list]);
					this.setSwallowTouches(st===1);
				}
				this._enterActionID.setValue(uim.getControlActionDataByFindIndex(sourceControlData.propertyDataFindIndex[ivy.DefaultSourceControlTypes.SCT_ELEMENT_AniButton_EnterAction_action]));
				this._outActionID.setValue(uim.getControlActionDataByFindIndex(sourceControlData.propertyDataFindIndex[ivy.DefaultSourceControlTypes.SCT_ELEMENT_AniButton_OutAction_action]));
				let bindIndex = uim.getControlIntDataByFindIndex(sourceControlData.propertyDataFindIndex[ivy.DefaultSourceControlTypes.SCT_ELEMENT_AniButton_BindKeyIndex_int]);
				let self = this;
				if (bindIndex >= 0) {
					this.setTouchEnterCallback(function () {
						if(self._enableBindTouchAction) {
							ivy.ControlManager.getInstance().setButtonState(bindIndex, ivy.ControlManager.ControlState.eTouchEnter, true);
						}
					});

					this.setTouchingCallback(function () {
						if (self._enableBindTouchAction) {
							ivy.ControlManager.getInstance().setButtonState(bindIndex, ivy.ControlManager.ControlState.eTouching, true);
						}
					});

					this.setTouchEndCallback(function(){
						if (self._enableBindTouchAction) {
							ivy.ControlManager.getInstance().setButtonState(bindIndex, ivy.ControlManager.ControlState.eTouching, false);
							ivy.ControlManager.getInstance().setButtonState(bindIndex, ivy.ControlManager.ControlState.eTouchEnd, true);
						}
					});

					this.setTouchCancelCallback(function(){
						if (self._enableBindTouchAction) {
							ivy.ControlManager.getInstance().setButtonState(bindIndex, ivy.ControlManager.ControlState.eTouching, false);
							ivy.ControlManager.getInstance().setButtonState(bindIndex, ivy.ControlManager.ControlState.eTouchEnd, true);
						}
					});

					this.setTouchDoubleCallback(function(){
						if (self._enableBindTouchAction) {
							ivy.ControlManager.getInstance().setButtonState(bindIndex, ivy.ControlManager.ControlState.eTouchDouble, true);
						}
					});
				}
			}
		}
	},

	update : function(dt) {
		this._super(dt);
		//TODO:测试是否会自动调用
		++this._lifeTimer;
		if (this._isTouching && this._touchingFunc) {
			this._touchingFunc(this);
		}
	},

	setTouchingCallback : function(func) {
		this._super(func);
		if (!this._usingUpdate) {
			this._usingUpdate = true;
			//this.schedule(schedule_selector(UIButton::update), 0.05f);
		}
	},
	setTouchDoubleCallback : function(func) {
		this._super(func);
		if (!this._usingUpdate) {
			this._usingUpdate = true;
			//this.schedule(schedule_selector(UIButton::update), 0.05f);
		}
	},
	setTouchEnable : function(enable) {
		if (this.touchMode_ === ivy.TouchMode.eMulitTouch) {
			this._mulitTouchEnable = enable
		} else {
			this._super(enable);
		}
	},
	resetButtonSureActionID : function(gameActionID) {
		this._buttonSureActionID = gameActionID;
	},
	setEnableBindTouchAction : function(enable) {
		this._enableBindTouchAction = enable;
	},
	getEnableBindTouchAction : function() {
		return this._enableBindTouchAction;
	},
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////protected:
	touchMode_ : ivy.UIBase.TouchMode.eSingleTouch,

	onTouchBegan : function(touch, event) {
		if (!this.isVisible()) {
			return false;
		}
		if (!this._enableUserTouch) {
			return false;
		}
		let uim = ivy.UIManager.getInstance();
		if (!uim.isSingleTouchEventAllow()) {
			return false;
		}
		if (this.getActionByTag(ivy.UIBase.CommonActionTAG.eEnterAction) || this.getActionByTag(ivy.UIBase.CommonActionTAG.eOutAction)) {
			return false;
		}

		let touchPoint = touch.getLocation();
		let touchRectInWorldTransform = this.getTouchRectInWorldTransform();

		if (cc.rectContainsPoint(touchRectInWorldTransform, touchPoint)) {
			this._isTouching = true;
			this._touchBeginItemPos = this.convertToWorldSpace(cc.p());
			if (this._touchEnterFunc) {
				this._touchEnterFunc(this);
			}

			this.stopAllActions();
			if (this._clickActionIndex >= 0) {
				this.runAction(ivy.CocosActionDataManager.getInstance().getGameActionBy(this._clickActionIndex));
			} else {
				switch (this._showType) {
					case ivy.UIButton.UIButtonShowType.eTwoPartsAniShowPressedCircle:
					case ivy.UIButton.UIButtonShowType.eTwoPartsAniShowPressedNotCircle:
						if (this._aniPlayer) {
							this._aniPlayer.resetAnimation(this._pressedAniID);
						}
						break;
					case ivy.UIButton.UIButtonShowType.eComputerAniShow:
					default:
						this.runAction(cc.scaleTo(0.05, 0.7));
						break;
				}
			}

			if (this._touchDoubleFunc) {
				if (this._checkDoubleTouch) {
					this._doubleTouchTimer = this._lifeTimer;
					this._checkDoubleTouch = false;
				} else {
					let curLifeTimer = this._lifeTimer;
					if (curLifeTimer - this._doubleTouchTimer < 5) {
						if (this._touchDoubleFunc) {
							this._touchDoubleFunc(this);
						}
						this._checkDoubleTouch = true;
					} else {
						this._doubleTouchTimer = this._lifeTimer;
					}
				}
			}
			return true;
		}
		return false;
	},
	onTouchMoved : function(touch, event) {
		let touchPoint = touch.getLocation();
		let touchRectInWorldTransform = this.getTouchRectInWorldTransform();
		if (cc.rectContainsPoint(touchRectInWorldTransform, touchPoint)) {
			//不在此处调用按中事件是由于部分机型按住不动不会调用到此处
			//因此滑动事件将放到循环中调用
			/*if (_touchingFunc)
				_touchingFunc(this);*/
		} else {
			if (this._isTouching) {
				this.stopAllActions();
				if (this._unClickActionIndex >= 0) {
					this.runAction(ivy.CocosActionDataManager.getInstance().getGameActionBy(this._unClickActionIndex));
				} else {
					switch (this._showType) {
						case ivy.UIButton.UIButtonShowType.eTwoPartsAniShowPressedCircle:
						case ivy.UIButton.UIButtonShowType.eTwoPartsAniShowPressedNotCircle: {
							if(this._aniPlayer) {
								this._aniPlayer.resetAnimation(this._normalAniID);
							}
							break;
						}
						case ivy.UIButton.UIButtonShowType.eComputerAniShow:
						default:
							this.runAction(cc.scaleTo(0.05, 1.0));
							break;
					}
				}
			}
			this._isTouching = false;
			if (this._touchCancelFunc) {
				this._touchCancelFunc(this);
			}
		}
	},
	onTouchEnded : function(touch, event) {
		if (this._isTouching) {
			this.stopAllActions();
			if (this._unClickActionIndex >= 0) {
				this.runAction(ivy.CocosActionDataManager.getInstance().getGameActionBy(this._unClickActionIndex));
			} else {
				switch (this._showType) {
					case ivy.UIButton.UIButtonShowType.eTwoPartsAniShowPressedCircle:
					case ivy.UIButton.UIButtonShowType.eTwoPartsAniShowPressedNotCircle: {
						if(this._aniPlayer) {
							this._aniPlayer.resetAnimation(this._normalAniID);
						}
						break;
					}
					case ivy.UIButton.UIButtonShowType.eComputerAniShow:
					default: {
						this.runAction(cc.scaleTo(0.05, 1.0));
						break;
					}
				}
			}
		}
		let touchEndItemPos = this.convertToWorldSpace(cc.p(0, 0));
		let touchPoint = touch.getLocation();
		let touchRectInWorldTransform = this.getTouchRectInWorldTransform();
		let uim = ivy.UIManager.getInstance();
		if (uim.isIgnoreScrollCheck()) {
			if (cc.rectContainsPoint(touchRectInWorldTransform, touchPoint)) {
				if (uim.isSingleTouchEventAllow()) {
					if (this._touchEndFunc && this._isTouching) {
						this._touchEndFunc(this);
					}
					if (this._isTouching && this._buttonSureActionID.valid()) {
						this.runAction(ivy.CocosActionDataManager.getInstance().getGameActionBy(this._buttonSureActionID));
					}
					uim.resetSingleTouchEventTimer();
				}
			} else {
				if (this._touchCancelFunc) {
					this._touchCancelFunc(this);
				}
			}
		} else {
			if (Math.abs(this._touchBeginItemPos.x - touchEndItemPos.x) < ivy.UIBase.TOUCH_MIN_VAILD_DIS &&
				Math.abs(this._touchBeginItemPos.y - touchEndItemPos.y) < ivy.UIBase.TOUCH_MIN_VAILD_DIS &&
				cc.rectContainsPoint(touchRectInWorldTransform, touchPoint)) {
				if (uim.isSingleTouchEventAllow()) {
					if (this._touchEndFunc && this._isTouching) {
						this._touchEndFunc(this);
					}
					if (this._isTouching && this._buttonSureActionID.valid()) {
						this.runAction(ivy.CocosActionDataManager.getInstance().getGameActionBy(this._buttonSureActionID));
					}
					uim.resetSingleTouchEventTimer();
				}
			} else {
				if (this._touchCancelFunc) {
					this._touchCancelFunc(this);
				}
			}
		}
		this._isTouching = false;
	},
	onTouchCancelled : function(touch, event) {
		if (this._isTouching) {
			this.stopAllActions();
			if (this._unClickActionIndex >= 0) {
				this.runAction(ivy.CocosActionDataManager.getInstance().getGameActionBy(this._unClickActionIndex));
			} else {
				switch (this._showType) {
					case ivy.UIButton.UIButtonShowType.eTwoPartsAniShowPressedCircle:
					case ivy.UIButton.UIButtonShowType.eTwoPartsAniShowPressedNotCircle: {
						if (this._aniPlayer) {
							this._aniPlayer.resetAnimation(this._normalAniID);
						}
						break;
					}
					case ivy.UIButton.UIButtonShowType.eComputerAniShow:
					default: {
						this.runAction(cc.scaleTo(0.05, 1.0));
						break;
					}
				}
			}
		}
		if (this._touchCancelFunc)
			this._touchCancelFunc(this);
	},
	//TODO: onTouchs 没有翻译
	// virtual void onTouchesBegan(const std::vector<cocos2d::Touch*>& touches, cocos2d::Event* event);
	// virtual void onTouchesMoved(const std::vector<cocos2d::Touch*>& touches, cocos2d::Event* event);
	// virtual void onTouchesEnded(const std::vector<cocos2d::Touch*>& touches, cocos2d::Event* event);
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////private:
	_enableBindTouchAction : true,
	//用于检测按键弹起时是否触发弹起事件
	//(例如 scrollview中的按钮拖动后不能相应)
	_touchBeginItemPos : null,//cocos2d::Point
	_isTouching : false,
	_invaildTouchID : -1,
	_curTouchID : -1,
	//用于检测双击
	_lifeTimer : 0,
	_doubleTouchTimer : 0,
	_checkDoubleTouch : true,
	_usingUpdate : false,
	_mulitTouchEnable : true,

	_clickActionIndex : -1,
	_unClickActionIndex : -1,
	_buttonSureActionID : null,//cc::GameActionID();
	_showType : 0,//ivy.UIButtonShowType.eComputerAniShow;
	_normalAniID : null,//cc::AnimationID
	_pressedAniID : null,//cc::AnimationID

});

ivy.UIButton.create = function (formName, blockName, sourceControlData) {
	return new ivy.UIButton(formName, blockName, sourceControlData);
};

ivy.UIButton.UIButtonShowType = {
	eComputerAniShow                    : 0,
	eTwoPartsAniShowPressedNotCircle    : 1,
	eTwoPartsAniShowPressedCircle       : 2,
};